﻿using Kinlo.MESDocking;
using log4net;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UIWindows.GlobalStatics;
using UIWindows.Models.Interact;
using UIWindows.Services.Context;
using UIWindows.Tools.Helper;
using UIWindows.Tools.MesHelper;
using XingLucifer.Devices;
using XingLucifer.IBase;
using XingLucifer.IBase.Enums;
using XingLucifer.IBase.Models.PLCInteraktion;

namespace UIWindows.Services.Handle
{
    [Attributes.TaskClassAttribute(TaskTypes.设备状态)]
    public class DeviceStatus : ServierBase
    {
        private static log4net.ILog _alarm;
        public DeviceStatus(DeviceConfigStatic deviceConfig, SystemConfigStatic systemConfig,
            UserConfigStatic userConfig, ParameterStatic parameterStatic, TemporaryStatic temporary, HomeStatic homeStatic, MesParameterStatic mesParameterStatic)
            : base(deviceConfig, systemConfig, userConfig, parameterStatic, temporary, homeStatic, mesParameterStatic)
        {
            _stopwatch = new Stopwatch();
            RunStatusTime();
            Action<string, string, string, string, string, long, DateTime, string, string, string, string> log = (barcode, interfaceName, result_message, str_post, str_result,
            time, dateTime, devicetype, type, logtype, url) => barcode.MesLog(interfaceName, result_message, str_post, str_result,
            time, dateTime, devicetype, type, logtype, url);
            Action<string, string, string> dialog = (interfaceName, messageEncoding, messageContent) => interfaceName.MESDialog(messageEncoding, messageContent);
            _interaction = new UploadMachineStatus(log, dialog);
        }

        private ushort device_status = 1;
        private Stopwatch _stopwatch;
        private StringBuilder stringBuilder = new StringBuilder(); 
        public override Task Handle(DataContext context)
        {
            if (_alarm == null) { _alarm = LogManager.GetLogger("plc_alarm"); }
            TaskService.Instance.RemoveTask(context);
            //if(!_parameterStatic.DecideParameter.EnableMES) return Task.CompletedTask;
            try
            {
                var plc = _deviceConfig.DeviceList.FirstOrDefault(x => x.ServiceName == context.ServiceName && x.TaskType == TaskTypes.扫描信号).Communication as OmronCIP;
                if (plc == null) { return Task.CompletedTask; }
                device_status = (ushort)_temporaryStatic.DeviceStatus[context.ServiceName];
                RunLog($"获取到的状态为：[{device_status}]", context: context);
                _stopwatch.Stop();
                // 1:自动运行 , 2  待机, 3 报警,4 手动,5 故障状态,6 维修状态,7  急停状态  
                if (device_status == 3 || device_status == 7)//有报警
                {
                    if (_temporaryStatic.PLCAlarmList.Count > 0)
                    {                       
                        stringBuilder.Clear();
                        List<PLCAlarmModel> plc_alarms = new List<PLCAlarmModel>();

                        for (int i = 0; i < 50; i++)
                        {
                            PLCAlarmArraryModel arrary_model = plc.ReadClass<PLCAlarmArraryModel>($"PC_MesAlarm[{i}]");
                            // plc.Communication.ReadClass(19000 + (i * 420), arrary_model);
                            plc_alarms.AddRange(arrary_model.PLCAlarm);
                        }

                        for (int i = 0; i < plc_alarms.Count; i++)
                        {
                            for (int j = 0; j < 30; j++)
                            {
                                int index = i * 30 + j;

                                if ((plc_alarms[i].Tip[j]|| plc_alarms[i].Warning[j]||plc_alarms[i].Alarm[j]) && index < _temporaryStatic.PLCAlarmList.Count)
                                {
                                    if (!_temporaryStatic.PLCAlarmList[index].IsHasAlarm) //有新报警
                                    {                                        
                                        _temporaryStatic.PLCAlarmList[index].Id = new Guid();
                                        _temporaryStatic.PLCAlarmList[index].IsHasAlarm = true;
                                        _temporaryStatic.PLCAlarmList[index].StartTime = DateTime.Now;
                                        if (!string.IsNullOrWhiteSpace(_temporaryStatic.PLCAlarmList[index].Message))
                                         MesOeeHelper.OeeWarning(_temporaryStatic.PLCAlarmList[index], _temporaryStatic, _parameterStatic, DialogLogHelper.MesLog, DialogLogHelper.MESDialog); 
                                    }
                                    //stringBuilder.AppendLine(_temporaryStatic.PLCAlarmList[index].Message);
                                    //_alarm.Info($"{DateTime.Now:yyyy/MM/dd HH:mm:ss.fff} ==> {_temporaryStatic.PLCAlarmList[index]}");

                                }                               
                                //if (plc_alarms[i].Warning[j])
                                //{
                                //    if (index < _temporaryStatic.PLCAlarmList.Count)
                                //    {
                                //        stringBuilder.AppendLine(_temporaryStatic.PLCAlarmList[index].Message);
                                //        _alarm.Info($"{DateTime.Now:yyyy/MM/dd HH:mm:ss.fff} ==> {_temporaryStatic.PLCAlarmList[index]}");
                                //    }
                                //}
                            }
                        }
                    }
                }
                else //为了不过多占用PLC交互资源，只要！=3 &&！=7 就当报警结束
                {
                    var alarms = _temporaryStatic.PLCAlarmList.Where(x => x.IsHasAlarm).ToList();
                    if (alarms.Any())
                    {                      
                        alarms.ForEach(x =>
                        {
                            x.IsHasAlarm = false;
                            x.EndTime = DateTime.Now;
                            MesOeeHelper.OeeWarning(x, _temporaryStatic, _parameterStatic, DialogLogHelper.MesLog, DialogLogHelper.MESDialog);
                        });                       
                    }
                }

                if (device_status == 2)// 待机
                {
                    _stopwatch.Start();
                    while (_stopwatch.ElapsedMilliseconds < (_parameterStatic.RunParameter.StandbyPopUpWindowTime * 1000))
                    {
                        if (device_status != 1)
                        {
                            return Task.CompletedTask;
                        }
                        Thread.Sleep(100);
                    }
                    _stopwatch.Stop();
                    //这里写达到待机弹窗时间后的逻辑

                }



            }
            catch (Exception ex)
            {
                RunLog($"异常：{ex}");
            }
            return Task.CompletedTask;
        }

        private string Exchange(int value) => value switch
        {
            1 => "3",
            2 => "1",
            3 => "3",
            4 => "2",
            5 => "4",
            _ => "1",
        };

        private Task RunStatusTime()
        {
            return Task.Run(() =>
            {
                var service_name = _systemConfig.SignalList.Select(x => x.Name).ToArray();
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                while (true)
                {
                    if (stopwatch.ElapsedMilliseconds > 975)
                    {
                        switch (device_status)
                        {
                            case 5:
                            case 4:
                            case 1:
                                _homeStatic.EquipmentTime.Manual++;
                                break;
                            case 2:
                                _homeStatic.EquipmentTime.Run++;
                                break;
                            case 3:
                                _homeStatic.EquipmentTime.Error++;
                                break;
                        }
                        stopwatch.Restart();
                    }
                    Thread.Sleep(20);
                }
            });
        }
    }
}
